package com.jule.goldfast.game.vavle.notice;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.core.jedis.StoredObjManager;
import com.jule.goldfast.base.enums.GameConst;
import com.jule.goldfast.base.enums.RedisConst;
import com.jule.goldfast.base.enums.RoleType;
import com.jule.goldfast.game.gameUtil.DealCardForTable;
import com.jule.goldfast.game.model.PlayerInfo;
import com.jule.goldfast.base.enums.PlayerStateEnum;
import com.jule.goldfast.game.play.AbstractTable;
import com.jule.goldfast.game.play.TableUtil;
import com.jule.goldfast.game.service.LogService;
import com.jule.goldfast.game.service.holder.FunctionIdHolder;
import com.jule.goldfast.game.utils.NumUtils;
import com.jule.goldfast.game.utils.log.TableLogUtil;
import com.jule.goldfast.log.service.LogReasons;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Executors;

/**
 * 广播通知处理类
 */
@Slf4j
public class NoticeBroadcastMessages {

    //获取当前桌子的赢家
    private static PlayerInfo getWinner(AbstractTable table) {
        //找到剩余的没有弃牌的玩家
        //获胜的用户
        PlayerInfo winner = null;
        for (PlayerInfo player : table.getInGamePlayers().values()) {
            //如果用户已是旁观状态，并且此座位上还是该用户存在，那么清除此用户的游戏中信息
            PlayerInfo playerInfoBySeatNum = table.getInGamePlayersBySeatNum().get(player.getSeatNum());
            if (player.getState().getValue() == PlayerStateEnum.spectator.getValue()
                    && null != playerInfoBySeatNum
                    && playerInfoBySeatNum.getPlayerId().equals(player.getPlayerId())) {
                table.standUp(player.getSeatNum(), player.getPlayerId(), "Settle");
                if (player.getRoleType() != null && player.getRoleType().equals(RoleType.ROBOT)) {
                    LoggerUtils.robot.info("Robot standUp reason settle id:" + player.getPlayerId() + ",gameId:" + table.getPlayType()
                            + ",roomId:" + table.getRoomId() + ",tableId:" + table.getTableId());
                }
            }

            if (player.getHandCards() == null) {
                log.debug(player.playerToString() + " -> handCards is null: " + (player.getHandCards() == null));
                //如果用户无手牌数据，那么做发牌操作
                DealCardForTable oc1 = new DealCardForTable(table.getRoomTableRelation(), table.getCurrGameOrderId());
                int[] cards = oc1.hair_card(table.giveCardCounts(), player.getPlayerId());
                player.setHandCards(cards);
            }
            if (null == winner) {
                winner = player;
                player.getHandCardTypeModel();
            } else {
                //比较两个玩家的牌大小，留下赢家。
                if (player != null) {
                    PlayerInfo tmp = table.getWinnerByCompareCards(winner, player);
                    winner = tmp;
                }
            }
        }
        return winner;
    }

    private static void winLoseList(AbstractTable table,
                                    List<JoloGame.JoloGame_TablePlay_PlayerSettleInfo> winList,
                                    List<JoloGame.JoloGame_TablePlay_PlayerSettleInfo> loseList,
                                    StringBuilder strLog) {
        try {
            //赢家
            PlayerInfo winner = getWinner(table);
            double winScore = 0;
            double logicScore = 0;
            //计算输家筹码
            for (PlayerInfo player : table.getInGamePlayers().values()) {
                //构建结构
                strLog.append("{seat:" + player.getSeatNum() + ",");
                strLog.append("userId:" + player.getPlayerId() + ",");
                strLog.append("nickName:" + player.getNickName() + ",");
                strLog.append("winLoseScore:" + player.getCurScore() + ",");
                strLog.append("betMultiple:" + player.getBetMultiple() + ",");
                strLog.append("ant:" + table.getRoomConfig().getAnte() + ",");

                //下注筹码
                double betScore = table.getRoomConfig().getAnte();
                //能输掉的筹码
                double loseScore = betScore > player.getPlayScoreStore() ? player.getPlayScoreStore() : betScore ;
                int type = player.getType();//计算对局奖励金额(此处分数计算和玩家下注额关系不大，只跟底注有关)
                winScore += table.getRoomConfig().getAnte() * (type == 1 ? 5 : type == 2 ? 4 : type == 3 ? 2 : 1);
                logicScore += table.getRoomConfig().getAnte();

                log.debug("----------------table ante：{},玩家当前牌型：{}",table.getRoomConfig().getAnte(),type);
                if (winner.getPlayerId().contains(player.getPlayerId())){
                    //我是赢家
                    continue;
                }
                //扣钱
                player.minusPlayScoreStore(loseScore , LogReasons.CommonLogReason.GAME_SETTLE);
                log.debug("玩家{},输了{}筹码~", player.getPlayerId(), loseScore);

                //构建返回消息
                JoloGame.JoloGame_TablePlay_PlayerSettleInfo.Builder winnerBuilder = JoloGame.JoloGame_TablePlay_PlayerSettleInfo.newBuilder();
                winnerBuilder.setUserId(player.getPlayerId())
                        .setSeatNum(player.getSeatNum())
                        .setWinLose(0)
                        .setWinLoseScore(loseScore)
                        .setPlayScoreStore(player.getPlayScoreStore())
                        .addAllHandCards(NumUtils.ConvertByte2IntArr(player.getCards()))
                        .setCardType(player.getCardType());
                winList.add(winnerBuilder.build());

                //机器人资金池x 操作
                oprRobotPool(player, loseScore, false);
            }

            //去除玩家自己的下注额(净胜)
            winScore -= table.getRoomConfig().getAnte();

            //杀量池操作z
            int pct = table.getCommonConfig().getTotalLosePct();
            StoredObjManager.incrByFloat(RedisConst.GAME_KILL_AMOUNT_POOL.getProfix(), Math.abs(winScore) * pct * 0.01);

            //系統補值
            logicScore -= table.getRoomConfig().getAnte();
            double systemGive = NumUtils.double2Decimal(winScore - logicScore);
            //StoredObjManager.incrByFloat(RedisConst.GAME_KILL_AMOUNT_POOL.getProfix(), Math.abs(systemGive) * pct * 0.01);
            oprRobotPool(winner, systemGive, false);

            //服务费
            double servicefee = NumUtils.double2Decimal(winScore * table.getRoomConfig().getServiceChargeRate());

            double wintemp = (winScore - servicefee);
            //计算赢家筹码
            double winPrePlayer = NumUtils.double2Decimal(wintemp);
            log.debug("玩家开始结算,桌上赢的筹码={},服务费={},扣除服务费对局奖励金额={}", winScore, servicefee, winPrePlayer);
            for (PlayerInfo player : table.getInGamePlayersBySeatNum().values()) {

                if (!winner.getPlayerId().equals(player.getPlayerId())){
                    continue;
                }
                JoloGame.JoloGame_TablePlay_PlayerSettleInfo.Builder loseBuilder = JoloGame.JoloGame_TablePlay_PlayerSettleInfo.newBuilder();
                //加钱
                player.addPlayScoreStore(winPrePlayer, LogReasons.CommonLogReason.GAME_SETTLE);

                //构建返回消息
                loseBuilder.setUserId(player.getPlayerId())
                        .setSeatNum(player.getSeatNum())
                        .setWinLose(1)
                        .setWinLoseScore(winPrePlayer)
                        .setPlayScoreStore(player.getPlayScoreStore())
                        .addAllHandCards(NumUtils.ConvertByte2IntArr(player.getCards()))
                        .setCardType(player.getCardType());
                winList.add(loseBuilder.build());

                //机器人资金池x 操作
                oprRobotPool(player, winPrePlayer, true);

                //发送结算日志
                LogService.OBJ.sendGameSettleLog(table, servicefee, player.getPlayerId());
            }

            List<String> winnerList = Arrays.asList(winner.getPlayerId());
            //发送输赢日志
            LogService.OBJ.sendLoseWinLog(table, winnerList,winPrePlayer);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }


    //TODO:新玩家入座 51001
    public static void playerSitDown(final AbstractTable table, String userId) {
        try {
            PlayerInfo player = table.getPlayer(userId);
            table.boardcastMessage(table.getTableId(),
                    JoloGame.JoloGame_Notice2Client_SitDownReq.newBuilder()
                            .setUserId(player.getPlayerId())
                            .setRoomId(table.getRoomId())
                            .setTableId(table.getTableId())
                            .setNickName(player.getNickName())
                            .setPlayScore(player.getPlayScoreStore())
                            .setSeatNum(player.getSeatNum())
                            .setIcon(player.getIcon())
                            .build(),
                    FunctionIdHolder.Game_Notice_SiteDown);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    //TODO:玩家站起 51002
    public static void playerStandUp(final AbstractTable table, String userId, int seatNum) {
        PlayerInfo player = null;
        try {
            player = table.getPlayer(userId);
            table.boardcastMessage(table.getTableId(),
                    JoloGame.JoloGame_Notice2Client_StandUpReq.newBuilder()
                            .setUserId(userId)
                            .setRoomId(table.getRoomId())
                            .setTableId(table.getTableId())
                            .setNickName(player != null ? player.getNickName() : "")
                            .setSeatNum(seatNum)
                            .setInGamePlayers(table.getInGamePlayers().size())
                            .build(),
                    FunctionIdHolder.Game_Notice_StandUp);
        } catch (Exception ex) {
            log.error("发送玩家站起Notice失败，userId->{}, roomId->{}, tableId->{}, ex->{}",
                    userId, table.getRoomId(), table.getTableId(), ex.getMessage(), ex);
        }
        if (null != player) {
            player.removePlayerInfo();//清空玩家数据
        }
    }

    //TODO:准备状态1：OK 0：等待

    /**
     * @param table
     * @param playerInfo 改变状态的对象
     */
    public static void readyStatus(final AbstractTable table, PlayerInfo playerInfo) {
        try {
            if (playerInfo == null) {
                return;
            }
            table.boardcastMessage(table.getTableId(), JoloGame.JoloGame_Notice2Client_ReadyReq.newBuilder()
                    .setUserId(playerInfo.getPlayerId())
                    .setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .setReadyStatus(playerInfo.getState().equals(PlayerStateEnum.game_ready) ? 1 : 0)
                    .build(), FunctionIdHolder.Game_Notice2Client_ReadyType);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    //TODO：牌局开始 51004
    public static void gameStart(AbstractTable tableInfo) {
        try {
            JoloGame.JoloGame_Notice2Client_GameStartReq.Builder gameStart =
                    JoloGame.JoloGame_Notice2Client_GameStartReq.newBuilder();
            gameStart.setRoomId(tableInfo.getRoomId())
                    .setTableId(tableInfo.getTableId())
                    .setGameOrderId(tableInfo.getCurrGameOrderId())
                    .setCountDownSec(tableInfo.getCommonConfig().getGameStartCountDownSec());

            tableInfo.boardcastMessage(tableInfo.getTableId(), gameStart.build(),
                    FunctionIdHolder.Game_Notice_GameStart);
            TableLogUtil.gameStart(FunctionIdHolder.Game_Notice_GameStart, "gameStart",
                    "" + tableInfo.getPlayType(), tableInfo.getRoomId(), tableInfo.getTableId(),
                    tableInfo.getCurrGameOrderId(), TableUtil.inGamePlayersBySeatNumToString(tableInfo), 0,
                    TableUtil.tableInfoToString(tableInfo));
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    //TODO：通知全部客户端->发牌轮->开始 51005
    public static void giveCardBoardcast(AbstractTable table) {
        try {
            JoloGame.JoloGame_Notice2Client_GiveCardRound_StartReq.Builder reqBuilder = JoloGame.JoloGame_Notice2Client_GiveCardRound_StartReq.newBuilder();
            reqBuilder.setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .addAllPlayerInfoList(TableUtil.getPlayersInTable(table));
            table.boardcastMessage(table.getTableId(), reqBuilder.build(), FunctionIdHolder.Game_Notice_GiveCardRound_Start);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }


    //TODO:通知全部客户端->下注轮次->玩家实施下注 51007
    public static void betRoundDoBet(AbstractTable table, PlayerInfo doBetPlayer) {
        try {
            JoloGame.JoloGame_Notice2Client_BetRound_DoBetReq.Builder reqBuilder = JoloGame.JoloGame_Notice2Client_BetRound_DoBetReq.newBuilder();
            reqBuilder.setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .setBetUserId(doBetPlayer.getPlayerId())
                    .setBetUserSeatNum(doBetPlayer.getSeatNum())
                    .setBetScore(doBetPlayer.getTotalAlreadyBetScore4Hand());

            table.boardcastMessage(table.getTableId(),
                    reqBuilder.build(),
                    FunctionIdHolder.Game_Notice_BetRound_DoBet);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * 广播所有玩家下注结果
     *
     * @param table
     */
    public static void allPlayerBetResultBroadcast(AbstractTable table) {
        try {
            JoloGame.JoloGame_Notice2Client_BetResultReq.Builder notice
                    = JoloGame.JoloGame_Notice2Client_BetResultReq.newBuilder();

            List<JoloGame.JoloGame_BetResultInfo> list = new ArrayList<>();

            Iterator<PlayerInfo> iter = table.getInGamePlayers().values().iterator();
            while (iter.hasNext()) {
                PlayerInfo playerInfo = iter.next();
                if(playerInfo.getIsDealer()==1){
                    continue;
                }
                JoloGame.JoloGame_BetResultInfo.Builder betResultInfo = JoloGame.JoloGame_BetResultInfo.newBuilder();
                betResultInfo.setPlayScoreStore(playerInfo.getCurScore())
                        .setBetScore(playerInfo.getTotalAlreadyBetScore4Hand())
                        .setSeatNum(playerInfo.getSeatNum())
                        .setUserId(playerInfo.getPlayerId());
                list.add(betResultInfo.build());
            }
            notice.setGameOrderId(table.getCurrGameOrderId())
                    .setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .addAllBetResultList(list);
            table.boardcastMessage(table.getTableId(),
                    notice.build(), FunctionIdHolder.Game_Notice2Client_BetResultType);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * 定庄广播
     *
     * @param tableInfo
     */
    public static void fixDealerBroadcast(AbstractTable tableInfo) {
        try {
            List<PlayerInfo> playerInfos = TableUtil.getSameRobDealerPlayers(tableInfo);

            List<String> ids = new ArrayList<>();
            for (PlayerInfo tmp : playerInfos) {
                if (tmp != null) {
                    tmp.setIsDealer(0);
                    ids.add(tmp.getPlayerId());
                }
            }
            PlayerInfo tmpPlayer = playerInfos.get(0);
            if (playerInfos.size() > 1) {
                Collections.sort(playerInfos, new Comparator<PlayerInfo>() {
                    @Override
                    public int compare(PlayerInfo o1, PlayerInfo o2) {
                        return (int) (o2.getPlayScoreStore() - o1.getPlayScoreStore());
                    }
                });

                double pct = Math.random();
                if (pct >= tableInfo.getCommonConfig().getRobDealerPct() / 100.0d) {
                    tmpPlayer = playerInfos.get(0);
                } else {
                    Random random = new Random();
                    int n = random.nextInt(playerInfos.size());
                    tmpPlayer = playerInfos.get(n);
               }
            }
            tmpPlayer.setIsDealer(1);
            tableInfo.setCurrDealerSeatNum(tmpPlayer.getSeatNum());

            JoloGame.JoloGame_Notice2Client_FixDealerReq.Builder
                    notice = JoloGame.JoloGame_Notice2Client_FixDealerReq.newBuilder();
            notice.setRoomId(tableInfo.getRoomId())
                    .setTableId(tableInfo.getTableId())
                    .setUserId(tmpPlayer.getPlayerId())
                    .setGameOrderId(tableInfo.getCurrGameOrderId())
                    .addAllUserIds(ids);
            log.info("51031返回->" + notice.toString());
            tableInfo.boardcastMessage(tableInfo.getTableId(), notice.build(), FunctionIdHolder.Game_Notice2Client_FixDealerType);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * 下注前广播的信息 51032
     *
     * @param table
     */
    public static void betBeforeBroadcast(final AbstractTable table) {
        try {
            JoloGame.JoloGame_Notice2Client_BetInfoReq.Builder
                    notice = JoloGame.JoloGame_Notice2Client_BetInfoReq.newBuilder();
            notice.setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .setCountDownSec(table.getCommonConfig().getBetCountDownSec());

            table.boardcastMessage(table.getTableId(),
                    notice.build(), FunctionIdHolder.Game_Notice2Client_BetInfoType);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * 广播下注倍数 51038
     * @param table
     */
    public static void betMultiple(AbstractTable table) {
        JoloGame.JoloGame_Notice2Client_BetMultipleInfoReq.Builder betMultipleInfo =
                JoloGame.JoloGame_Notice2Client_BetMultipleInfoReq.newBuilder();
        betMultipleInfo.setGameOrderId(table.getCurrGameOrderId())
                .setRoomId(table.getRoomId())
                .setTableId(table.getTableId())
                .addAllBtnsMultiple(table.getRoomConfig().getDoubleList());

        Iterator<PlayerInfo> iter = table.getInGamePlayers().values().iterator();
        while (iter.hasNext()) {
            PlayerInfo playerInfo = iter.next();

            table.boardcastMessageSingle(playerInfo.getPlayerId(), betMultipleInfo.build(),
                    FunctionIdHolder.Game_Notice2Client_BetMultipleInfoType);
        }

    }


    private static void fillHandCardsInfo(AbstractTable table, List<JoloGame.JoloGame_HandCardsInfo> handCardsInfos) {
        try {
            //判断策略值
            int initKillPool = Integer.parseInt(StoredObjManager.get(RedisConst.ROBOT_INIT_KILL_POOL.getProfix()));
            int initRobotPool = Integer.parseInt(StoredObjManager.get(RedisConst.ROBOT_INIT_ROBOT_POOL.getProfix()));

            double x = Double.parseDouble(StoredObjManager.get(RedisConst.ROBOT_POOL_CURRENT_MONEY.getProfix())) + initRobotPool;

            double z = Double.parseDouble(StoredObjManager.get(RedisConst.GAME_KILL_AMOUNT_POOL.getProfix())) + initKillPool;

            double max = table.getCommonConfig().getStrategyMaxPct();
            double min = table.getCommonConfig().getStrategyMinPct();

            log.debug("AI机器人策略比值x={},z={}", String.valueOf(x), String.valueOf(z));
            if (x > max * z ){
                //机器人输
                log.debug("AI机器人策略 x > {}*z ,机器人应该输", max);
                doExchangeCard(table,false);
            }else if (x < min * z){
                //机器人赢
                log.debug("AI机器人策略 x < {}*z ,机器人应该赢", min);
                doExchangeCard(table,true);
            }else {
                log.debug("AI机器人策略正常发牌、不做操作");
            }
        }catch (Exception ex){
            log.error("机器人操作失败 ex = {}",ex);
        }

        Iterator<PlayerInfo> iter = table.getInGamePlayers().values().iterator();
        while (iter.hasNext()) {
            PlayerInfo playerInfo = iter.next();
            List<Integer> cards = NumUtils.ConvertByte2IntArr(playerInfo.getCards());
            JoloGame.JoloGame_HandCardsInfo.Builder handCards = JoloGame.JoloGame_HandCardsInfo.newBuilder();
            handCards.setUserId(playerInfo.getPlayerId())
                    .addAllHandCards(cards)
                    .setCardType(playerInfo.getType());
            handCardsInfos.add(handCards.build());
        }
    }

    /**
     * 换牌
     * @param robotWin
     * @param table
     */
    private static void doExchangeCard(AbstractTable table, boolean robotWin){
        PlayerInfo winner = getWinner(table);

        //无需换牌
        if (winner.getRoleType() == RoleType.ROBOT && robotWin ){
            return;
        }

        //无需换牌
        if (winner.getRoleType() != RoleType.ROBOT && !robotWin){
            return;
        }

        //换牌操作
        //输家换成赢家
        int[] loserCard = null;
        for (Integer seat : table.getInGamePlayers().keySet()){
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (player.getRoleType() != winner.getRoleType()){
                loserCard = player.getHandCards();

                int[] arrHandCards = winner.getHandCards();
                player.setHandCards(arrHandCards);
                player.setCards(NumUtils.ConvertInt2ByteArr(arrHandCards));
                player.setType(player.getCardType());
                break;
            }
        }

        //赢家换成输家
        for (Integer seat : table.getInGamePlayers().keySet()) {
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (!player.getPlayerId().equals(winner.getPlayerId())){
                continue;
            }
            player.setHandCards(loserCard); //玩家看牌后则为手牌赋值
            player.setCards(NumUtils.ConvertInt2ByteArr(loserCard));
            player.setType(player.getCardType());
        }
    }

    /**
     * 看牌广播 51033
     *
     * @param table
     */
    public static void pressCardBroadcast(AbstractTable table) {
        try {
            JoloGame.JoloGame_Notice2Client_HandCardsListReq.Builder
                    notice = JoloGame.JoloGame_Notice2Client_HandCardsListReq.newBuilder();

            notice.setCountDownSec(table.getCommonConfig().getOpenCardsCD())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .setRoomId(table.getRoomId())
                    .setTableId(table.getTableId());

            List<JoloGame.JoloGame_HandCardsInfo> handCardsInfos = new ArrayList<>();
            fillHandCardsInfo(table, handCardsInfos);
            notice.addAllHandCardsList(handCardsInfos);

            table.boardcastMessage(table.getTableId(),
                    notice.build(), FunctionIdHolder.Game_Notice2Client_HandCardListType);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }


    //TODO:通知全部客户端->结算动画 51013
    public static void settleAnimationBroadcast(AbstractTable table) {
        Long time = System.currentTimeMillis();
        try {
            StringBuilder strLog = new StringBuilder();
            strLog.append("[");

            List<JoloGame.JoloGame_TablePlay_PlayerSettleInfo> winList = new ArrayList<>();
            List<JoloGame.JoloGame_TablePlay_PlayerSettleInfo> loseList = new ArrayList<>();
            winLoseList(table, winList, loseList, strLog);
            JoloGame.JoloGame_Notice2Client_SettleRound_SettleReq.Builder reqBuilder = JoloGame.JoloGame_Notice2Client_SettleRound_SettleReq.newBuilder();
            reqBuilder.setRoomId(table.getRoomId())
                    .setTableId(table.getTableId())
                    .setGameOrderId(table.getCurrGameOrderId())
                    .addAllSettleWinList(winList)
                    .addAllSettleLoseList(loseList)
                    .setGameWheelNumber(table.getGameWheelNumber());
            log.debug("当前得游戏轮数：{}",table.getGameWheelNumber());
            table.boardcastMessage(table.getTableId(),
                    reqBuilder.build(), FunctionIdHolder.Game_Notice_SettleRound_SettleResult);


            if (strLog.indexOf(",") > 0) {
                strLog.replace(strLog.length() - 1, strLog.length(), "");
            }
            strLog.append("]");
            TableLogUtil.settle(FunctionIdHolder.Game_Notice_SettleRound_SettleResult, "settleAnimationBroadcast", table.getPlayType() + "",
                    table.getRoomId(), table.getTableId(), strLog.toString());
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        long cost = System.currentTimeMillis() - time;
        if (cost > 1000) {
            log.error("settleAnimationBroadcast() 超时" + cost);
        }
    }

    /**
     * 发送玩家进入消息 51039
     * @param table
     */
    public static void sendPlayerInNotice(AbstractTable table){
        try {
            JoloGame.JoloGame_Notice2Client_PlayersIn.Builder
                    notice = JoloGame.JoloGame_Notice2Client_PlayersIn.newBuilder();

            notice.setGameOrderId(table.getCurrGameOrderId())
                    .setGameId(String.valueOf(table.getPlayType()))
                    .setRoomId(table.getRoomId())
                    .setTableId(table.getTableId());

            table.boardcastMessage(table.getTableId(),
                    notice.build(), FunctionIdHolder.Game_Notice2Client_PlayersIn);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * 通知机器人离座、回收金币
     * @param table
     * @param player
     */
    public static void sendLeaveNotice(AbstractTable table, PlayerInfo player){
        if (player.getRoleType() != RoleType.ROBOT){
            return;
        }

        //离座通知构建
        JoloGame.JoloGame_Notice2Client_leaveReq.Builder notice = JoloGame.JoloGame_Notice2Client_leaveReq.newBuilder();
        notice.setRoomId(table.getRoomId())
                .setTableId(table.getTableId())
                .setUserId(player.getPlayerId());

        //发送通知
        table.boardcastMessage(table.getTableId(), notice.build(), FunctionIdHolder.Game_Notice2Client_leavel);
    }

    /**
     * 机器人资金池 X 操作
     * @param player
     * @param score
     */
    private static void oprRobotPool(PlayerInfo player, double score, boolean win){
        if (player == null || player.getRoleType() != RoleType.ROBOT){
            return;
        }

        double incr = score;
        if (!win){
            incr = -score;
        }

        StoredObjManager.incrByFloat(RedisConst.ROBOT_POOL_CURRENT_MONEY.getProfix(), incr);
    }
}
